home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / disk / misc / NoDirCache.lha / NoDirCache.c next >
Encoding:
C/C++ Source or Header  |  2000-09-22  |  10.2 KB  |  393 lines

  1. /*    NoDirCache.c    use hdwrench.library to change a partition from DirCache to
  2.  *                    something safe.
  3.  *        $VER: NoDirCache.c 44.1(22.9.2000) © Wizardess Designs and Joanne Dow 1999 All rights reserved
  4.  *
  5.  *        © Copyright 1999 by Joanne Dow, Wizardess Designs
  6.  *        All Rights Reserved
  7.  *
  8.  *        Presumes "scsi.device" else enter "DEVICE devicename".
  9.  */
  10. #include    <stdio.h>
  11. #include    <stdarg.h>
  12. #include    <string.h>
  13. #include    <ctype.h>
  14. #include    <stdlib.h>
  15. #include    <math.h>
  16. #include    <dos.h>
  17. #include    <exec/types.h>
  18. #include    <exec/ports.h>
  19. #include    <exec/libraries.h>
  20. #include    <exec/io.h>
  21. #include    <exec/nodes.h>
  22. #include    <exec/lists.h>
  23. #include    <exec/tasks.h>
  24. #include    <exec/memory.h>
  25. #include    <exec/execbase.h>
  26. #include    <devices/trackdisk.h>
  27. #include    <libraries/dos.h>
  28. #include    <libraries/dosextens.h>
  29. #include    <dos/filehandler.h>
  30. #include    <devices/hardblocks.h>
  31. #include    <devices/scsidisk.h>
  32. #include    <intuition/intuition.h>
  33. #include    <workbench/workbench.h>
  34. #include    <workbench/icon.h>
  35. #include    <workbench/startup.h>
  36. #include    <dos/rdargs.h>
  37. #include    <dos/dostags.h>
  38.  
  39. #include    <proto/dos.h>
  40. #include    <proto/exec.h>
  41. #include    <pragmas/exec_pragmas.h>
  42. #include    <pragmas/disk_pragmas.h>
  43. #include    <pragmas/dos_pragmas.h>
  44.  
  45. #include    "HDWrench.h"
  46. #include    "HDWrench_pragmas.h"
  47. #define        USE_SUGGESTED_MESSAGES
  48.  
  49. struct HDWLibrary    *HDWBase = NULL;
  50.  
  51. #define TEMPLATE "TYPE/K/A,DEVICE/K,UNIT/N/K/A,FILE/K/A"
  52. #define NUM_ARGS 4
  53. #define FFS            0x444f5301
  54. #define FFS_INTL    0x444f5303
  55. #define DIRCACHE    0x444f5305
  56. #define DIRCACHEI    0x444f5307
  57.  
  58. char hexits [] = "0123456789abcdef";
  59. char spaces [] = "                                                ";
  60.  
  61. enum { ARG_TYPE, ARG_DEVICE, ARG_UNIT, ARG_FILE };
  62.  
  63. LONG             ArgArray [ NUM_ARGS ];
  64.  
  65. char*            membuffer        = NULL;
  66. BOOL            deviceopen        = FALSE;
  67. struct RDArgs*    Args             = NULL;
  68. BOOL            aborted            = FALSE;
  69. ULONG            testnum;
  70.  
  71. typedef union smallbootblock
  72. {
  73.     UBYTE         bd_Bytes[512];    // NB: This is the MINIMUM size we
  74.     UWORD         bd_Words[256];    // can have here. It MAY be extended
  75.     ULONG         bd_Longs[128];    // if ddBlockBytes is larger.
  76.     struct         RigidDiskBlock bd_RDB;
  77.     struct         BadBlockBlock bd_BB;
  78.     struct         PartitionBlock bd_PB;
  79.     struct         FileSysHeaderBlock bd_FHB;
  80.     struct         LoadSegBlock bd_LSB;
  81. } SmallBootBlock;
  82.  
  83. #define    sbb_Bytes    sbb_Data->bd_Bytes
  84. #define    sbb_Words    sbb_Data->bd_Words
  85. #define    sbb_Longs    sbb_Data->bd_Longs
  86. #define sbb_RDB        sbb_Data->bd_RDB
  87. #define    sbb_BB        sbb_Data->bd_BB
  88. #define    sbb_PB        sbb_Data->bd_PB
  89. #define    sbb_FHB        sbb_Data->bd_FHB
  90. #define    sbb_LSB        sbb_Data->bd_LSB
  91. #define sbb_ID        sbb_Data->bd_Longs [ 0 ]
  92. #define sbb_Next    sbb_Data->bd_Longs [ 4 ]
  93. #define sbb_Check    sbb_Data->bd_Longs [ 2 ]
  94.  
  95. BOOL    handlePartition ( SmallBootBlock* sbb_Data, ULONG newDosType, ULONG blocksize );
  96. void    usage ( void );
  97. int        btrap ( void );
  98. void    gone ( void );
  99.  
  100. int
  101. main ( int argc, char **argv)
  102. {
  103.     char*             filename;
  104.     char             devicename[60];
  105.     ULONG             baseunit;
  106.     ULONG             ffstype;
  107.     ULONG             sizememneeded;
  108.  
  109.     ULONG             rsuccess;
  110.     USHORT             rwsuccess;
  111.  
  112.     ArgArray [ 0 ] =
  113.     ArgArray [ 1 ] =
  114.     ArgArray [ 2 ] =
  115.     ArgArray [ 3 ] = 0 ;
  116.  
  117.     puts( "NoDirCache - Switch DirCache partitions to \"FFS\" or \"FFS_INTL\".\n" );
  118.  
  119.     atexit( gone );
  120.     if ( onbreak ( &btrap ))
  121.     {
  122.         printf ( "Break trap not installed!" );
  123.         exit ( 20 );
  124.     }
  125.  
  126.     Args = ReadArgs( TEMPLATE, ArgArray, NULL );
  127.     if ( Args )
  128.     {
  129.         //    ARG_TYPE, ARG_DEVICE, ARG_UNIT, ARG_FILE
  130.         memset ( devicename, 0, 60 );
  131.         if ( ArgArray [ ARG_TYPE ] != NULL )
  132.         {
  133.             if ( stricmp( (char*) ArgArray [ ARG_TYPE ], "FFS" ) == 0 )
  134.                 ffstype = 0x444f5301L;
  135.             else
  136.             if ( stricmp( (char*) ArgArray [ ARG_TYPE ], "FFS_INTL" ) == 0 )
  137.                 ffstype = 0x444f5303L;
  138.             else
  139.             {
  140.                 usage();
  141.                 exit( 20 );
  142.             }
  143.         }
  144.  
  145.         if ( ArgArray [ ARG_DEVICE ] != NULL )
  146.             strncpy ( devicename, (char *)    ArgArray [ ARG_DEVICE ], 59 );
  147.         else
  148.         {
  149.             usage();
  150.             exit( 20 );
  151.         }
  152.  
  153.         baseunit    = *(ULONG *)    ArgArray [ ARG_UNIT ];
  154.  
  155.         filename    = (char *)    ArgArray [ ARG_FILE ];
  156.  
  157.         printf ( "Type    = 0x%lx\n", ffstype );
  158.         printf ( "Unit    = %ld\n", baseunit );
  159.         printf ( "Filename    = %s\n", filename );
  160.         printf ( "Devicename    = %s\n\n\n", devicename);
  161.  
  162.         if ( strlen( filename ) > 248 )
  163.         {
  164.             printf ( "Filename: %s is too long!\n", filename );
  165.             exit( 10 );
  166.         }
  167.  
  168.         if (( HDWBase = ( struct HDWLibrary *) OpenLibrary ( HDWBaseName, 0)) == NULL )
  169.         {
  170.             printf ( "Failed to open HDWBase!\n");
  171.             exit ( 20 );
  172.         }
  173.     }
  174.     else
  175.     {
  176.         usage ();
  177.         exit ( 20 );
  178.     }
  179.  
  180.     // All setup and places to go. Let's read in the RDBs since we need them
  181.     // for a lot of things. If we place them in memory we can parse them easier.
  182.     // Let's use the raw RDBs because they are in handy structure format for
  183.     // reading.
  184.     
  185.     printf ( "Attempting to open: %s:%d\n", devicename, baseunit );
  186.     deviceopen = HDWOpenDevice ( devicename, baseunit );
  187.     if ( !deviceopen )
  188.     {
  189.         printf ( "No device was opened!\n");
  190.         exit ( 20 );
  191.     }
  192.     printf ( "Attempting to read RDBs into library.\n");
  193.  
  194.     rwsuccess = ReadRDBs ( );
  195.  
  196.     if ( rwsuccess == success )
  197.     {
  198.         sizememneeded = 0;
  199.         rsuccess = OutMemRDBStructs ( NULL, &sizememneeded, 0 );
  200.  
  201.         if ( rsuccess == E_NOERROR )
  202.         {
  203.             printf ( "Need %ld bytes of buffer for mountfile.\n", sizememneeded );
  204.             membuffer = malloc ( sizememneeded );
  205.             if ( membuffer )
  206.             {
  207.                 rsuccess = OutMemRDBStructs ( membuffer, &sizememneeded, sizememneeded );
  208.                 if ( rsuccess == E_NOERROR )
  209.                 {
  210.                     // Now we have things in memory. We can do something
  211.                     // with it all.
  212.                     // generate pointer to base block.
  213.                     SmallBootBlock*    sbb_Data = (SmallBootBlock*) &membuffer[0];
  214.                     ULONG            blocksize = sbb_RDB.rdb_BlockBytes;
  215.                     ULONG            offset = sbb_RDB.rdb_RDBBlocksLo;
  216.                     if ( offset > 16L )
  217.                     {
  218.                         printf ( "Illegal RDB start block found: %ld\n", offset );
  219.                         exit ( 20 );
  220.                     }
  221.                     // Generate physical block size
  222.                     if (( blocksize != 512L )
  223.                     &&  ( blocksize != 1024L )
  224.                     &&  ( blocksize != 2048L )
  225.                     &&  ( blocksize != 4096L )
  226.                     &&  ( blocksize != 8192L )
  227.                     &&  ( blocksize != 16384L ))
  228.                     {
  229.                         printf ( "Illegal blocksize found: %ld\n", blocksize );
  230.                         exit ( 20 );
  231.                     }
  232.                     // Now scan for partitions.
  233.                     while (( (ULONG) sbb_Data - (ULONG) membuffer ) < sizememneeded )
  234.                     {
  235.                         if ( sbb_PB.pb_ID == IDNAME_PARTITION )
  236.                         {
  237.                             // We have one.
  238.                             if ( !handlePartition( sbb_Data, ffstype, blocksize ))
  239.                             {
  240.                                 // Error attempting to fix partition
  241.                                 exit( 20 );
  242.                             }
  243.                         }
  244.                         sbb_Data ++;
  245.                     }
  246.                     // OK, we're happy with the new RDBs - we hope.
  247.                     printf ( "Flush the old RDBs from hdwrench.library\n" );
  248.                     HDWCloseDevice ();
  249.                     deviceopen = HDWOpenDevice ( devicename, baseunit );
  250.                     if ( !deviceopen )
  251.                     {
  252.                         printf ( "No device was opened!\n");
  253.                         exit ( 20 );
  254.                     }
  255.                     rsuccess = InMemRDBStructs ( membuffer,        // Start of RDB buffer
  256.                                                  sizememneeded,    // Size of source buffer
  257.                                                  baseunit );    // Presumed unit
  258.                     if ( rsuccess == 0 )
  259.                         printf ( "RDB's successfully back in hdwrench.library\n" );
  260.                     else
  261.                     {
  262.                         printf ( "RDB's failed to load back into hdwrench.library %d\n", rsuccess );
  263.                         printf ( "We must stop here with RDBs mismatching the actual DosTypes.\n" );
  264.                         exit ( 20 );
  265.                     }
  266.  
  267.                     // Write the file
  268.                     printf ( "\nWriting mountfile \"%s\"\n", filename );
  269.                     rsuccess = WriteMountfile ( filename, "sys:", baseunit );
  270.                     if ( rsuccess == 0 )
  271.                         printf ( "You should have a new %s waiting.\n", filename );
  272.                     else
  273.                         printf ( "MountFile write failed: %d\n", rsuccess );
  274.                     // And finally write back the RDBs to the disk
  275.                     printf ( "Writing RDBs to disk\n" );
  276.                     rwsuccess = WriteRDBs (  );
  277.                     if ( rwsuccess == 0 )
  278.                         printf ( "You should have a new RDBs waiting on the disk.\n" );
  279.                     else
  280.                     {
  281.                         if ( rwsuccess != 0xffff )
  282.                             printf ( "DOODOO CITY! RDB Write failed: %d\n", rwsuccess );
  283.                         else
  284.                             printf ( "RDB Write failed because this version does not have it supported.\n" );
  285.                     }
  286.                 }
  287.                 else
  288.                 {
  289.                     printf ( "    Could not read the RDBs: %d\n", rsuccess );
  290.                 }
  291.             }
  292.         }
  293.         else
  294.             printf ( "Mountfile size write failed: %d\n", rsuccess );
  295.     }
  296.     else
  297.         printf ( "InMemMountfile failed, %ld\n", rsuccess );
  298.  
  299.  
  300. cleanup:
  301.  
  302.     exit ( 0 );
  303. }
  304.  
  305. void usage ( void )
  306. {
  307.     printf ( "NoDirCache %s\n", TEMPLATE );
  308.     printf ( "So I'm a stinker. Only device will default to scsi.device. You are\n" );
  309.     printf ( "getting a freebie revised mountfile as well as an unDirCached disk\n" );
  310.     printf ( "whether you want it or not. The TYPE parameter must be either \"FFS\"\n" );
  311.     printf ( "or \"FS_INTL\".\n" );
  312. }
  313.  
  314. int btrap ( void )
  315. {
  316.     printf ( "\n***BREAK***\n" );
  317.     exit(20);
  318.     return 0;
  319. }
  320.  
  321. void gone ( void )
  322. {
  323.     if ( deviceopen )
  324.     {
  325.         printf ( "Closing opened device\n" );
  326.         HDWCloseDevice();
  327.         deviceopen = FALSE;
  328.     }
  329.  
  330.     if ( membuffer )
  331.     {
  332.         free ( membuffer );
  333.         membuffer = NULL;
  334.     }
  335.  
  336.     if ( Args )
  337.         FreeArgs ( Args );
  338.  
  339.     if ( HDWBase )
  340.         CloseLibrary ( ( struct Library *) HDWBase );
  341.     HDWBase = NULL;
  342. }
  343.  
  344. BOOL handlePartition ( SmallBootBlock* sbb_Data, ULONG newDosType, ULONG blocksize )
  345. {
  346.     struct DosEnvec*    dev = (struct DosEnvec*) sbb_PB.pb_Environment;
  347.     ULONG                firstblock;
  348.     USHORT                ecode;
  349.  
  350.     // We have a partition block. Report type.
  351.     printf ( "DosType = %lx found for partition %s:\n", dev->de_DosType, sbb_PB.pb_DriveName + 1 );
  352.  
  353.     // For testing porpoises...
  354.     if (( dev->de_DosType == DIRCACHE )
  355.     ||  ( dev->de_DosType == DIRCACHEI ))
  356.     {
  357.         BootBlock*    bb = (BootBlock*) malloc( sizeof ( BootBlock ) + blocksize - 512 );
  358.         //    So fix it....
  359.         if ( bb == NULL )
  360.         {
  361.             printf ( "Memory panic - out of memory!\n" );
  362.             return FALSE;
  363.         }
  364.         // First change the RDB dostype
  365.         printf ( "    Fix RDB DosType\n" );
  366.         dev->de_DosType = newDosType;
  367.  
  368.         firstblock = dev->de_LowCyl
  369.                    * dev->de_Surfaces
  370.                    * dev->de_BlocksPerTrack;    // Real physical number....
  371.         // Correct for old method of setting alternate logical block sizes.
  372.         firstblock *= ( dev->de_SizeBlock << 2 )  / blocksize;
  373.  
  374.         // Now actually read firstblock;
  375.         printf ( "    Now read firstblock at %ld\n", firstblock );
  376.         bb->bb_BlockNum = firstblock;    // Only value really needed
  377.         ecode = RawRead ( bb, blocksize );
  378.         if ( ecode == success )
  379.         {
  380.             printf ( "    DosType read is %lx\n", bb->bb_Data.bd_Longs [ 0 ] );
  381.             bb->bb_Data.bd_Longs [ 0 ] = newDosType;
  382.             ecode = RawWrite ( bb );
  383.             if ( ecode != success )
  384.                 printf ( "    !!!!Kiddo, for some reason the write back failed. You're in deep doodoo!\n" );
  385.             else
  386.                 printf ( "    Writeback succeeded\n" );
  387.         }
  388.  
  389.         free( bb );
  390.     }
  391.     return TRUE;
  392. }
  393.